<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script type="text/javascript">
        function compose(middleware) {
            return function(context, next) {
                //last called middleware #
                let index = -1
                return dispatch(0)

                function dispatch(i) {
                    if (i <= index) return Promise.reject(new Error('next() called multiple times'))
                    index = 1
                    let fn = middleware[i]
                    if (i === middleware.length) fn = next
                    if (!fn) return Promise.resolve()
                    try {
                        return Promise.resolve(fn(context, function next() {
                            return dispatch(i + 1)
                        }))
                    } catch (err) {
                        return Promise.reject(err)
                    }
                }
            }
        }
    </script>
</body>

</html>